package model;

/**
 * Represents the tiles.
 * 
 * @author Richard
 * 
 */
public class Tile {
	public enum Rotation {
		DEGREES_0, DEGREES_90, DEGREES_180, DEGREES_270
	}

	private Rotation rotation = Rotation.DEGREES_0;
	private TileType type;
	
	private int[][] cachedConnections = null;

	public void rotate()
	{
		switch (this.rotation)
		{
			case DEGREES_0:
				rotation = Rotation.DEGREES_90;
				break;
			case DEGREES_90:
				rotation = Rotation.DEGREES_180;
				break;
			case DEGREES_180:
				rotation = Rotation.DEGREES_270;
				break;
			case DEGREES_270:
				rotation = Rotation.DEGREES_0;
				break;
		}
		this.calculateConnections();
	}
	
	public int[] findConnection(int index)
	{
		switch (this.rotation)
		{
		case DEGREES_0:
		break;
		case DEGREES_90: index = (index + 9) % 12;
		break;
		case DEGREES_180: index = (index + 6) % 12;
		break;
		case DEGREES_270: index = (index + 3) % 12;
		break;
		}
		int[] connections = type.findConnection(index);
		for (int i=0; i<connections.length; i++)
		{
			switch (this.rotation)
			{
			case DEGREES_0:
			break;
			case DEGREES_90: connections[i] = (connections[i] + 3) % 12;
			break;
			case DEGREES_180: connections[i] = (connections[i] + 6) % 12;
			break;
			case DEGREES_270: connections[i] = (connections[i] + 9) % 12;
			break;
			}
		}
		return connections;
	}
	
	public TileType getType() {
		return this.type;
	}

	/**
	 * @return the rotation
	 */
	public Rotation getRotation() {
		return rotation;
	}

	/**
	 * @param rotation the rotation to set
	 */
	public void setRotation(Rotation rotation) {
		this.rotation = rotation;
		this.calculateConnections();
	}

	/**
	 * @param type the type to set
	 */
	public void setType(TileType type) {
		this.type = type;
	}
	
	public int[][] getConnections() {
		if(this.cachedConnections == null) {
			this.calculateConnections();
		}
		return this.cachedConnections;
	}
	
	private void calculateConnections() {
		int[][] connections = this.type.getConnections();
		if(connections.length > 0) {
			this.cachedConnections = new int[connections.length][];
			for(int x = 0; x < connections.length; x++) {
				this.cachedConnections[x] = new int[connections[x].length];
				for(int y = 0; y < connections[x].length; y++) {
					switch (this.rotation)
					{
						case DEGREES_0:
							this.cachedConnections[x][y] = connections[x][y];
							break;
						case DEGREES_90:
							this.cachedConnections[x][y] = (connections[x][y] + 3) % 12;
							break;
						case DEGREES_180:
							this.cachedConnections[x][y] = (connections[x][y] + 6) % 12;
							break;
						case DEGREES_270:
							this.cachedConnections[x][y] = (connections[x][y] + 9) % 12;
							break;
					}
				}
			}
		} else {
			this.cachedConnections = new int[0][0];
		}
	}
}
